package com.tsfyun.scm.service.impl.base;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tsfyun.common.base.constant.CacheConstant;
import com.tsfyun.common.base.dto.Result;
import com.tsfyun.common.base.util.ResultUtil;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.scm.client.BaseDataClient;
import com.tsfyun.scm.client.CustomsCodeClient;
import com.tsfyun.scm.client.SystemDataClient;
import com.tsfyun.scm.service.base.ISystemCacheService;
import com.tsfyun.scm.system.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description:
 * @since Created in 2020/4/8 13:53
 */
@Slf4j
@Service
public class SystemCacheServiceImpl implements ISystemCacheService {

    @Autowired
    private BaseDataClient baseDataClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SystemDataClient systemDataClient;

    @Autowired
    private CustomsCodeClient customsCodeClient;

    @Override
    public List<BaseDataVO> getBaseDataByTpe(String type) {
        if(StringUtils.isEmpty(type)) {
            return null;
        }
        Object value = redisTemplate.opsForValue().get(CacheConstant.BASE_DATA_LIST + "::" + type);
        if(StringUtils.isEmpty(value)) {
            log.warn("缓存未击中基础数据：【{}】，开始远程调用获取",type);
            Result<List<BaseDataVO>> result = baseDataClient.getByType(type);
            ResultUtil.checkRemoteResult(result,"获取基础配置数据异常，请您稍后再试");
            return result.getData();
        } else {
            log.debug("缓存击中基础数据：【{}】",type);
            return JSONArray.parseArray(value.toString(), BaseDataVO.class);
        }
    }

    @Override
    public BaseDataVO getBaseDataByTpeAndCode(String type, String code) {
        if(StringUtils.isEmpty(type) || StringUtils.isEmpty(code)) {
            return null;
        }
        List<BaseDataVO> baseDataVOS = getBaseDataByTpe(type);
        if(CollUtil.isNotEmpty(baseDataVOS)) {
            return baseDataVOS.stream().collect(Collectors.toMap(BaseDataVO::getCode, Function.identity())).get(code);
        }
        return null;
    }

    @Override
    public CountryVO getCountryById(String id) {
        if(StringUtils.isEmpty(id)) {
            return null;
        }
        List<CountryVO> countrys = allCountry();
        if(CollUtil.isNotEmpty(countrys)) {
            Map<String,CountryVO> countryMap = countrys.stream().collect(Collectors.toMap(CountryVO::getId,Function.identity()));
            return countryMap.get(id);
        }
        log.error(String.format("未找到国家数据【{}】",id));
        return null;
    }

    /**
     * 获取所有的国家
     * @return
     */
    public List<CountryVO> allCountry() {
        Object value = redisTemplate.opsForValue().get(CacheConstant.COUNTRY_LIST + "::" + "select");
        List<CountryVO> countrys;
        if(StringUtils.isEmpty(value)) {
            log.warn("缓存未击中国家数据，开始远程调用获取");
            Result<List<CountryVO>> result = systemDataClient.countrySelect( );
            ResultUtil.checkRemoteResult(result,"获取国家数据异常，请您稍后再试");
            countrys = result.getData();
        } else {
            log.debug("缓存击中国家数据");
            countrys = JSONArray.parseArray(value.toString(), CountryVO.class);
        }
        return countrys;
    }

    /**
     * 获取所有的税收分类编码
     * @return
     */
    public List<TaxCodeBaseVO> allTaxCodeBase() {
        Object value = redisTemplate.opsForValue().get(CacheConstant.TAX_CODE_LIST + "::" + "select");
        List<TaxCodeBaseVO> taxCodeBases;
        if(StringUtils.isEmpty(value)) {
            log.warn("缓存未击中税收分类数据，开始远程调用获取");
            Result<List<TaxCodeBaseVO>> result = systemDataClient.taxSelect( );
            ResultUtil.checkRemoteResult(result,"获取税收分类数据异常，请您稍后再试");
            taxCodeBases = result.getData();
        } else {
            log.debug("缓存击中税收分类数据");
            taxCodeBases = JSONArray.parseArray(value.toString(), TaxCodeBaseVO.class);
        }
        return taxCodeBases;
    }

    @Override
    public CountryVO getCountryByName(String name) {
        if(StringUtils.isEmpty(name)) {
            return null;
        }
        List<CountryVO> countrys = allCountry();
        if(CollUtil.isNotEmpty(countrys)) {
            Map<String,CountryVO> countryMap = countrys.stream().collect(Collectors.toMap(CountryVO::getName,Function.identity()));
            return countryMap.get(name);
        }
        log.error(String.format("未找到国家数据【{}】",name));
        return null;
    }

    @Override
    public UnitVO getUnitById(String id) {
        if(StringUtils.isEmpty(id)) {
            return null;
        }
        List<UnitVO> units = allUnits();
        if(CollUtil.isNotEmpty(units)) {
            Map<String,UnitVO> unitMap = units.stream().collect(Collectors.toMap(UnitVO::getId,Function.identity()));
            return unitMap.get(id);
        }
        log.error(String.format("未找到单位数据【{}】",id));
        return null;
    }

    /**
     * 获取所有的单位
     * @return
     */
    public List<UnitVO> allUnits() {
        Object value = redisTemplate.opsForValue().get(CacheConstant.UNIT_LIST + "::" + "select");
        List<UnitVO> units;
        if(StringUtils.isEmpty(value)) {
            log.warn("缓存未击中单位数据，开始远程调用获取");
            Result<List<UnitVO>> result = systemDataClient.unitSelect( );
            ResultUtil.checkRemoteResult(result,"获取单位数据异常，请您稍后再试");
            units = result.getData();
        } else {
            log.debug("缓存击中单位数据");
            units = JSONArray.parseArray(value.toString(), UnitVO.class);
        }
        return units;
    }

    @Override
    public UnitVO getUnitByName(String name) {
        if(StringUtils.isEmpty(name)) {
            return null;
        }
        List<UnitVO> units = allUnits();
        if(CollUtil.isNotEmpty(units)) {
            Map<String,UnitVO> unitMap = units.stream().collect(Collectors.toMap(UnitVO::getName,Function.identity()));
            return unitMap.get(name);
        }
        log.error(String.format("未找到单位数据【{}】",name));
        return null;
    }

    @Override
    public BaseDataVO getBaseDataByTpeAndDecCode(String type, String decCode) {
        if(StringUtils.isEmpty(type) || StringUtils.isEmpty(decCode)) {
            return null;
        }
        List<BaseDataVO> baseDataVOS = getBaseDataByTpe(type);
        if(CollUtil.isNotEmpty(baseDataVOS)) {
            return baseDataVOS.stream().collect(Collectors.toMap(BaseDataVO::getDecCode, Function.identity())).get(decCode);
        }
        return null;
    }

    @Override
    public CustomsCodeVO getCustomsCodeInfo(String customsCode) {
        if(StringUtils.isEmpty(customsCode)){return null;}
        Object value = redisTemplate.opsForValue().get(CacheConstant.CUSTOMS_DATA_CODE + "::" + customsCode);
        CustomsCodeVO customsCodeVO;
        if(StringUtils.isEmpty(value)) {
            log.warn("缓存未击中海关编码【{}】数据，开始远程调用获取",customsCode);
            Result<CustomsCodeVO> result = customsCodeClient.detail(customsCode);
//            ResultUtil.checkRemoteResult(result,String.format("获取海关编码【%s】数据异常",customsCode));
            ResultUtil.checkRemoteResult(result,result.getMessage());
            customsCodeVO = result.getData();
        } else {
            log.debug("缓存击中海关编码【{}】数据",customsCode);
            customsCodeVO = JSONObject.parseObject(JSONObject.toJSONString(value),CustomsCodeVO.class);
        }
        return customsCodeVO;
    }

    @Override
    public List<CustomsElementsVO> getCustomsElementsByHsCode(String customsCode) {
        Object value = redisTemplate.opsForValue().get(CacheConstant.CUSTOMS_ELEMENTS_HS_CODE + "::" + customsCode);
        List<CustomsElementsVO> customsElementsVOS;
        if(StringUtils.isEmpty(value)) {
            log.warn("缓存未击中要素数据，开始远程调用获取");
            Result<List<CustomsElementsVO>> result = customsCodeClient.elementDetail(customsCode);
            ResultUtil.checkRemoteResult(result,"获取要素数据异常");
            customsElementsVOS = result.getData();
        } else {
            log.debug("缓存击中要素数据");
            customsElementsVOS = JSONArray.parseArray(JSONObject.toJSONString(value), CustomsElementsVO.class);
        }
        return customsElementsVOS;
    }

    @Override
    public TaxCodeBaseVO getTaxCodeBaseByCode(String code) {
        if(StringUtils.isEmpty(code)) {
            return null;
        }
        List<TaxCodeBaseVO> taxCodeBases = allTaxCodeBase();
        if(CollUtil.isNotEmpty(taxCodeBases)) {
            Map<String,TaxCodeBaseVO> dataMap = taxCodeBases.stream().collect(Collectors.toMap(TaxCodeBaseVO::getId,Function.identity()));
            return dataMap.get(code);
        }
        log.error(String.format("未找到税收分类数据【{}】",code));
        return null;
    }

    @Override
    public List<TariffCustomsCodeVO> tariffCustoms() {
        Object value = redisTemplate.opsForValue().get(CacheConstant.ALL_TARIFF_CUSTOMS_CODE + "::" + "all");
        List<TariffCustomsCodeVO> tariffCustomsCodeVOs;
        if(StringUtils.isEmpty(value)) {
            log.warn("缓存未击中最惠国税率大于0的海关编码数据，开始远程调用获取");
            Result<List<TariffCustomsCodeVO>> result = customsCodeClient.tariffCustoms( );
            ResultUtil.checkRemoteResult(result,"获取海关编码数据异常");
            tariffCustomsCodeVOs = result.getData();
        } else {
            log.debug("缓存击中最惠国税率大于0的海关编码数据");
            tariffCustomsCodeVOs = JSONArray.parseArray(JSONObject.toJSONString(value), TariffCustomsCodeVO.class);
        }
        return tariffCustomsCodeVOs;
    }


}
